home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Libris Britannia 4
/
science library(b).zip
/
science library(b)
/
TECHNICA
/
COMPUTER
/
H254.ZIP
/
IRITSM3S.ZIP
/
IRIT
/
INTRNRML.C
< prev
next >
Wrap
C/C++ Source or Header
|
1991-11-10
|
5KB
|
153 lines
/*****************************************************************************
* "Irit" - the 3d polygonal solid modeller. *
* *
* Written by: Gershon Elber Ver 0.2, Aug. 1990 *
******************************************************************************
* Module to interplate internal vertices using vertices on the given *
* convex boundary OriginalVList. All internal vertices are assumed to be in *
* the interior of the convex region defined by OriginalVList or on its *
* boundary. *
*****************************************************************************/
#include <math.h>
#include "program.h"
#include "geomat3d.h"
#include "intrnrml.h"
/* #define DEBUG To define polygon (with normals printing routine. */
static void UpdateOneVertexNormal(VertexStruct *VUpdate,
PolygonStruct *OriginalPl);
#ifdef DEBUG
static void PrintPolygon(PolygonStruct *Pl);
#endif /* DEBUG */
/*****************************************************************************
* For each polygon in PlList update any vertex normal which is zero to an *
*interpolated value using the Original polygon vertex list OriginalVList. *
* All the new vertices are enclosed within the original polygon which *
* must be convex as well. *
*****************************************************************************/
void UpdateVerticesNormals(PolygonStruct *PlList, PolygonStruct *OriginalPl)
{
VertexStruct *V, *VHead;
while (PlList) {
V = VHead = PlList -> V;
do {
if (APX_EQ(V -> Normal[0], 0.0) &&
APX_EQ(V -> Normal[1], 0.0) &&
APX_EQ(V -> Normal[2], 0.0)) {
/* This vertex need to be updated. */
UpdateOneVertexNormal(V, OriginalPl);
}
V = V -> Pnext;
}
while (V != NULL && V != VHead);
PlList = PlList -> Pnext;
}
}
/*****************************************************************************
* Update one vertex normal be a convex blend of boundary vertices normals *
*****************************************************************************/
static void UpdateOneVertexNormal(VertexStruct *VUpdate,
PolygonStruct *OriginalPl)
{
VertexStruct *V, *OriginalVList = OriginalPl -> V;
V = OriginalVList;
do {
if (Colinear3Vertices(V, VUpdate, V -> Pnext)) {
/* Interpolate the normal according to the edge vertices VUpdate */
/* is on and according to the distance of VUpdate to edge ends. */
InterpNrmlBetweenTwo(VUpdate, V, V -> Pnext);
return;
}
V = V -> Pnext;
}
while (V != NULL && V != OriginalVList);
/* If we are here then the point is not on the polygon boundary and in */
/* that case we simply use the polygon normal as an approximation. */
PT_COPY(VUpdate -> Normal, OriginalPl -> Plane);
}
/*****************************************************************************
* Returns TRUE iff the 3 vertices are colinear. *
*****************************************************************************/
int Colinear3Vertices(VertexStruct *V1, VertexStruct *V2, VertexStruct *V3)
{
RealType l;
VectorType V12, V23, V;
if (PT_EQ(V1 -> Pt, V2 -> Pt) || PT_EQ(V2 -> Pt, V3 -> Pt))
return TRUE;
PT_SUB(V12, V1 -> Pt, V2 -> Pt);
PT_SUB(V23, V2 -> Pt, V3 -> Pt);
/* Make sure the middle point is in fact in the middle. */
if (V12[0] * V23[0] < -EPSILON ||
V12[1] * V23[1] < -EPSILON ||
V12[2] * V23[2] < -EPSILON)
return FALSE;
VecCrossProd(V, V12, V23);
l = PT_LENGTH(V);
return APX_EQ(l, 0.0);
}
/*****************************************************************************
* Returns TRUE iff the 3 vertices are colinear. *
*****************************************************************************/
void InterpNrmlBetweenTwo(VertexStruct *V, VertexStruct *V1, VertexStruct *V2)
{
RealType t1, t2;
VectorType Vec1, Vec2;
PT_SUB(Vec1, V -> Pt, V1 -> Pt);
PT_SUB(Vec2, V -> Pt, V2 -> Pt);
t1 = PT_LENGTH(Vec1);
t2 = PT_LENGTH(Vec2);
PT_COPY(Vec1, V1 -> Normal);
PT_COPY(Vec2, V2 -> Normal);
PT_SCALE(Vec1, t2);
PT_SCALE(Vec2, t1);
PT_ADD(V -> Normal, Vec1, Vec2);
PT_NORMALIZE(V -> Normal);
}
#ifdef DEBUG
/*****************************************************************************
* Print the content of the given polygon, to standard output. *
*****************************************************************************/
static void PrintPolygon(PolygonStruct *Pl)
{
VertexStruct *V = Pl -> V,
*VHead = V;
do {
printf(" %10lg %10lg %10lg (%10lg %10lg %10lg)",
V -> Pt[0], V -> Pt[1], V -> Pt[2],
V -> Normal[0], V -> Normal[1], V -> Normal[2]);
if (IS_INTERNAL_EDGE(V))
printf(" (Internal)\n");
else
printf("\n");
V = V -> Pnext;
}
while (V!= NULL && V != VHead);
}
#endif /* DEBUG */